#include "qlsavpacketqueue.h"

QLsAVPacketQueue::QLsAVPacketQueue()
	: m_firstPkt(nullptr)
	, m_lastPkt(nullptr)
	, m_nbPackets(0)
	, m_size(0)
	, m_mutex(SDL_CreateMutex())
	, m_cond(SDL_CreateCond())
{
}

QLsAVPacketQueue::~QLsAVPacketQueue()
{
	Clear();
	SDL_DestroyMutex(m_mutex);
	SDL_DestroyCond(m_cond);
}

/* 入队 */
void QLsAVPacketQueue::Enqueue(AVPacket *pkt)
{
	if (av_dup_packet(pkt) < 0) return;

	AVPacketList *pkt1 = (AVPacketList*)av_malloc(sizeof(AVPacketList));
	if (!pkt1) return;
	pkt1->pkt = *pkt;
	pkt1->next = NULL;

	SDL_LockMutex(m_mutex);

	if (!m_lastPkt) m_firstPkt = pkt1;
	else m_lastPkt->next = pkt1;
	m_lastPkt = pkt1;
	m_nbPackets++;
	m_size += pkt1->pkt.size;
	SDL_CondSignal(m_cond);

	SDL_UnlockMutex(m_mutex);
}

/* 获取队头包 */
bool QLsAVPacketQueue::Get(AVPacket *pkt)
{
	bool res = false;

	SDL_LockMutex(m_mutex);

	if(m_firstPkt)
	{
		*pkt = m_firstPkt->pkt;
		res = true;
	}

	SDL_UnlockMutex(m_mutex);

	return res;
}

/* 出队 */
void QLsAVPacketQueue::Dequeue()
{
	SDL_LockMutex(m_mutex);

	AVPacketList *pkt1 = m_firstPkt;
	if(pkt1)
	{
		m_firstPkt = pkt1->next;
		if (!m_firstPkt) m_lastPkt = nullptr;
		m_nbPackets--;
		m_size -= pkt1->pkt.size;
		av_free(pkt1);
	}

	SDL_UnlockMutex(m_mutex);
}

/* 提取对头包 = 获取队头包 + 出队 */
bool QLsAVPacketQueue::PopFront(AVPacket *pkt)
{
	bool res = false;

	SDL_LockMutex(m_mutex);

	AVPacketList *pkt1 = m_firstPkt;
	if(pkt1)
	{
		*pkt = m_firstPkt->pkt;

		m_firstPkt = pkt1->next;
		if (!m_firstPkt) m_lastPkt = nullptr;
		m_nbPackets--;
		m_size -= pkt1->pkt.size;
		av_free(pkt1);

		res = true;
	}

	SDL_UnlockMutex(m_mutex);

	return res;
}

/* 清空 */
void QLsAVPacketQueue::Clear()
{
	AVPacketList *pkt, *pkt1;

	SDL_LockMutex(m_mutex);

	for(pkt = m_firstPkt; pkt != NULL; pkt = pkt1)
	{
		pkt1 = pkt->next;
		av_packet_unref(&pkt->pkt);
		av_freep(&pkt);
	}
	m_lastPkt = NULL;
	m_firstPkt = NULL;
	m_nbPackets = 0;
	m_size = 0;

	SDL_UnlockMutex(m_mutex);
}
